package com.missilike.core.utils;

import org.apache.commons.lang3.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.Date;

public class DateUtils {
    public enum DatePattern {
        /**
         * 年-月-日
         */
        day("yyyy-MM-dd"),
        /**
         * 年-月-日  时
         */
        hour("yyyy-MM-dd HH"),
        /**
         * 年-月-日  时:分
         */
        minute("yyyy-MM-dd HH:mm"),
        /**
         * 年-月-日  时:分:秒
         */
        second("yyyy-MM-dd HH:mm:ss"),
        /**
         * 年-月-日'T'时:分:秒
         */
        secondISO("yyyy-MM-dd'T'HH:mm:ss"),
        /**
         * 月-日  时:分
         */
        monthMinuteSimple("MM-dd HH:mm"),
        /**
         * 月.日  时:分
         */
        monthMinuteSimpleDot("MM.dd HH:mm"),
        /**
         * 年.月.日  时:分
         */
        yearMonthMinuteSimpleDot("yy.MM.dd HH:mm"),
        /**
         * 时:分
         */
        minuteSimple("HH:mm"),
        /**
         * 月-日
         */
        monthDay("MM-dd"),
        /**
         * 年月日时分秒
         */
        secondSimple("yyyyMMddHHmmss"),;

        private DatePattern(String value) {
            this.value = value;
        }

        private String value;
    }

    private static final DatePattern DEFAULT_DATE_PATTERN = DatePattern.second;


    public static String dateToString(Date date) {
        SimpleDateFormat format = new SimpleDateFormat(DEFAULT_DATE_PATTERN.value);
        return format.format(date);
    }

    public static String dateToString(Date date, DatePattern formatPattern) {
        SimpleDateFormat format = new SimpleDateFormat(formatPattern.value);
        return format.format(date);
    }

    public static String dateToString(Date date, String formatPattern) {
        SimpleDateFormat format = new SimpleDateFormat(formatPattern);
        return format.format(date);
    }

    public static Date stringToDate(String dateString) {
        SimpleDateFormat format = new SimpleDateFormat(DEFAULT_DATE_PATTERN.value);
        Date date = null;
        try {
            date = format.parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return date;
    }

    public static String dateStringFormat(String dateString, DatePattern formatPattern) {
        if (StringUtils.isEmpty(dateString)) {
            return StringUtils.EMPTY;
        }
        return dateToString(stringToDate(dateString), formatPattern.value);
    }

    public static Date stringToDate(String dateString, DatePattern formatPattern) {
        SimpleDateFormat format = new SimpleDateFormat(formatPattern.value);
        Date date = null;
        try {
            date = format.parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return date;
    }

    public static String getDateEndTime(Date date) {
        return DateUtils.getDateEndTime(DateUtils.dateToString(date, DatePattern.day));
    }

    public static String getDateEndTime(String date) {
        if (StringUtils.isEmpty(date)) {
            return StringUtils.EMPTY;
        }
        return LocalDate.parse(date)
                .atTime(23, 59, 59)
                .toString();
    }

    public static Date localDateTimeToDate(LocalDateTime localDateTime) {
        Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
        return Date.from(instant);
    }

    public static LocalDateTime dateToLocalDateTime(Date date) {
        Instant instant = date.toInstant();
        return instant.atZone(ZoneId.systemDefault()).toLocalDateTime();
    }

    public static LocalDate dateToLocalDate(Date date) {
        Instant instant = date.toInstant();
        return instant.atZone(ZoneId.systemDefault()).toLocalDate();
    }

    public static Duration diff(Date startDate, Date endDate) {
        return Duration.between(dateToLocalDateTime(startDate), dateToLocalDateTime(endDate));
    }

    public static Long sub2Min(Date startDate, Date endDate) {
        if (startDate == null || endDate == null) {
            return 0L;
        }
        long second = (endDate.getTime() - startDate.getTime()) / 1000;
        if (second <= 0) {
            return 0L;
        }

        return (second / 60) + (second % 60 > 0 ? 1 : 0);
    }



}
